package com.dong.auth.security.authentication;

import com.dong.auth.security.crypto.PasswordEncoder;
import com.dong.auth.security.exception.AuthenticationException;
import com.dong.auth.security.exception.AuthenticationServiceException;
import com.dong.auth.security.exception.BadCredentialsException;
import com.dong.auth.security.userdetails.SecurityUser;
import com.dong.auth.security.userdetails.SecurityUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DaoAuthenticationProvider extends AbstractAuthenticationProvider{
    private final static Logger logger = LoggerFactory.getLogger(DaoAuthenticationProvider.class);

    private PasswordEncoder passwordEncoder;
    private SecurityUserService securityUserService;
    @Override
    protected SecurityUser retrieveUser(String username) throws AuthenticationException {
        SecurityUser loadedUser = this.getSecurityUserService().loadUserByUsername(username);
        if (loadedUser == null) {
            //没有从系统中查询到登录用户的信息
            throw new AuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");
        }
        return loadedUser;
    }

    @Override
    protected void additionalAuthenticationChecks(SecurityUser userDetails, Authentication authentication) throws AuthenticationException {
        if (authentication.getCredentials() == null) {
            logger.error("授权失败, 因为没有密码");
            throw new BadCredentialsException("登录密码为空！");
        }
        //比较密码
        if (!this.passwordEncoder.matches(authentication.getCredentials(),userDetails.getPassword())) {
            //密码错误
            logger.error("Failed to authenticate since password does not match stored value");
            throw new BadCredentialsException("Bad credentials");
        }

    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }

    public PasswordEncoder getPasswordEncoder() {
        return passwordEncoder;
    }

    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    public SecurityUserService getSecurityUserService() {
        return securityUserService;
    }

    public void setSecurityUserService(SecurityUserService securityUserService) {
        this.securityUserService = securityUserService;
    }
}
